/**
 * 自动引入模板，在原有 sw-precache 插件默认模板基础上做的二次开发
 *
 * 因为是自定导入的模板，项目一旦生成，不支持随 sw-precache 的版本自动升级。
 * 可以到 Lavas 官网下载 basic 模板内获取最新模板进行替换
 *
 */

/* eslint-disable */

'use strict';

var precacheConfig = [["/blog/2019/04/14/外边距合并问题/index.html","ee6c7e4fd5dcf88d71bc91f83d36c36d"],["/blog/2020/03/02/MyEclipse 2017-2018 安装与破解教程/index.html","0d70d28cdaf1d051fef29caea5abec73"],["/blog/2020/03/02/同步_异步 & 阻塞_非阻塞/index.html","91afad1274609becaccf5c9f17c2c94b"],["/blog/2020/03/02/学习Markdown/index.html","cc1ac984e3fa8737560d4d86ac3fec38"],["/blog/2020/03/04/JAVA高效网络库Okhttp3/index.html","327c0974f21694521adf3f2dd6eb1e38"],["/blog/2020/03/07/变量和类型/index.html","f099bd0cee85bbece297c02609794177"],["/blog/archives/2019/04/index.html","af526136fabf7a85664bdda0bad65534"],["/blog/archives/2019/index.html","48d927ef5ec8ca999a3476e18f4d99ab"],["/blog/archives/2020/03/index.html","97c3312daa83b184a709b10fd809ddba"],["/blog/archives/2020/index.html","a6751b1e15eaa6701083b8acecf2920e"],["/blog/archives/index.html","ca65882f02ab2e60ad05c890f84dd199"],["/blog/categories/IDE开发工具/index.html","53088052bd1141c2dda64593ae05f58c"],["/blog/categories/JAVA/index.html","61a7e377ad284db1798312573614669e"],["/blog/categories/Java基础/index.html","625868b19c734a0ba0724b1eacc94e7b"],["/blog/categories/Markdown/index.html","5375d37a8efb7a8cad4291d546350ebe"],["/blog/categories/index.html","b2a5bf852fab51864950653c2a9b3329"],["/blog/categories/前端/index.html","fda6eb6b81843c26e42de6b353683735"],["/blog/categories/知识点/index.html","30b6733e312357f339814d76954b81ec"],["/blog/css/main.css","9fb9a41d9b967d9c979aaab994e338a6"],["/blog/images/algolia_logo.svg","88450dd56ea1a00ba772424b30b7d34d"],["/blog/images/apple-touch-icon-next.png","fce961f0bd3cd769bf9c605ae6749bc0"],["/blog/images/avatar.gif","7a2fe6b906600a9354cece6d9ced2992"],["/blog/images/bg1.jpg","805577b6fc3d8f17af9fd2edbb043834"],["/blog/images/bg2.jpg","9984d2adefa73720220fab5784a7e892"],["/blog/images/bg3.jpg","5a6f3c500e260fb71ae1bfc0d1f965ad"],["/blog/images/cc-by-nc-nd.svg","3b009b0d5970d2c4b18e140933547916"],["/blog/images/cc-by-nc-sa.svg","cf2644b7aa5ebd3f5eab55329b4e7cb7"],["/blog/images/cc-by-nc.svg","e63bcae937a1ae4cb6f83d8a1d26893c"],["/blog/images/cc-by-nd.svg","78359b1307baffc2d0e8cffba5dee2dd"],["/blog/images/cc-by-sa.svg","525d2a82716fe9860a65cf0ac5e231a0"],["/blog/images/cc-by.svg","bd656500a74c634b4ff1333008c62cd8"],["/blog/images/cc-zero.svg","2d6242e90c3082e7892cf478be605d26"],["/blog/images/favicon-16x16-next.png","8edd8ec650e4829cec1fbb977399623c"],["/blog/images/favicon-16x16-next1.png","b8975923a585dbaa8519a6068e364947"],["/blog/images/favicon-32x32-next.png","bde6f759dabad78bcfe231f8567df69e"],["/blog/images/favicon-32x32-next1.png","5a029563fe3214c96f68b46556670ea1"],["/blog/images/logo.svg","88985471c188e5c5a765a8f233c54df5"],["/blog/images/quote-l.svg","a9d75107c4d7e31612f98e78be0979f9"],["/blog/images/quote-r.svg","5f902def9e09af7fc41e4cf86ad1a0f9"],["/blog/index.html","136398529ec1c1dc247c19bd237d095c"],["/blog/js/algolia-search.js","365bb42f0c4b83787d2e988e9a0dbd6d"],["/blog/js/bookmark.js","9631924f730be981fe8f8c14eb2c0afe"],["/blog/js/clicklove.js","5a87dd19400b2870ef6734f56cfe2208"],["/blog/js/local-search.js","c5ee1638d834b20f8c9aacab2b7f4205"],["/blog/js/motion.js","e8073e03493feb145528c4bdbe613d70"],["/blog/js/next-boot.js","c47528c6b7d3020a3dfd391c262dfebd"],["/blog/js/schemes/muse.js","00003a337eaddaf997e3a3ca2b9958e6"],["/blog/js/schemes/pisces.js","449ab6c338dc543eec24a7151b0456ab"],["/blog/js/utils.js","e8a7cdcf92c2949aff6e401486c8a462"],["/blog/lib/anime.min.js","864a144dbbc956381a47679ec57ab06c"],["/blog/lib/font-awesome/css/font-awesome.css","c495654869785bc3df60216616814ad1"],["/blog/lib/font-awesome/css/font-awesome.min.css","269550530cc127b6aa5a35925a7de6ce"],["/blog/lib/font-awesome/fonts/fontawesome-webfont.eot","674f50d287a8c48dc19ba404d20fe713"],["/blog/lib/font-awesome/fonts/fontawesome-webfont.woff","fee66e712a8a08eef5805a46892932ad"],["/blog/lib/pjax/CHANGELOG.html","eba9e22ea7e5789993f3dcff0d9a9338"],["/blog/lib/pjax/README.html","aab25a75ac9e85d7b16a249ab3f53ca1"],["/blog/lib/pjax/example/example.js","693e793ab23257ba91ba22933172555d"],["/blog/lib/pjax/example/forms.html","638f03020bda466ce97543748a1aae73"],["/blog/lib/pjax/example/index.html","d3e0c55b1df5549b43039f3486ab0e54"],["/blog/lib/pjax/example/page2.html","4874709d55fb885ed3cbbc202ad2fea0"],["/blog/lib/pjax/example/page3.html","d8f0af8d82d3e2a06f777335e1f72056"],["/blog/lib/pjax/index.js","3ef2531a2c7a333d0f7a232dee4ef9e8"],["/blog/lib/pjax/lib/abort-request.js","4bdc59dae5e5b29ee8484873804d1f8c"],["/blog/lib/pjax/lib/eval-script.js","43601f1c12e67f29197cd09304078739"],["/blog/lib/pjax/lib/events/off.js","a32b62a0efb066d81d1aac58c90fb3bd"],["/blog/lib/pjax/lib/events/on.js","a77e3da8fecd8a92550152189c6c6986"],["/blog/lib/pjax/lib/events/trigger.js","bfb14e27ee61ce0fd3ac52af0726c663"],["/blog/lib/pjax/lib/execute-scripts.js","8ff50f47e6593e4c060d6fabc09a0b7f"],["/blog/lib/pjax/lib/foreach-els.js","cc92a783c79bf1a9c29cdbf152b104c5"],["/blog/lib/pjax/lib/foreach-selectors.js","59e887fda038986c2f6418d281e3beb3"],["/blog/lib/pjax/lib/is-supported.js","3a3ac8e8cba4b4e4d29a7894a4d06177"],["/blog/lib/pjax/lib/parse-options.js","0287c332b98fb1ebe2e6c2793ddcc85e"],["/blog/lib/pjax/lib/proto/attach-form.js","e976eb2a5bdc97c6237876bd88f6cbdb"],["/blog/lib/pjax/lib/proto/attach-link.js","3671625d0900e7c630b6785c85527e84"],["/blog/lib/pjax/lib/proto/handle-response.js","05556fa655572885181e9caa2295d08c"],["/blog/lib/pjax/lib/proto/log.js","40caea5f9f971381fc5204416d06dfcc"],["/blog/lib/pjax/lib/proto/parse-element.js","e2f6b3d683bb6bd3d7d3acc2bfbb93dd"],["/blog/lib/pjax/lib/send-request.js","77e4c002534f12d39817326a372db618"],["/blog/lib/pjax/lib/switches-selectors.js","2246ad5dd990e5eefbe6e6c11ea7d59d"],["/blog/lib/pjax/lib/switches.js","ef5ed5e542dbb93be1a5c1b72d8b63db"],["/blog/lib/pjax/lib/uniqueid.js","b47ca3fddf0a67c9cc5f0c7dcb56f974"],["/blog/lib/pjax/lib/util/clone.js","43f6c73e044eebcdd6d3088075b17f90"],["/blog/lib/pjax/lib/util/contains.js","ec87af9c5172cb2872b764997bd07c6f"],["/blog/lib/pjax/lib/util/extend.js","07c19e94a35ea2f0ce68163b42f7ddd4"],["/blog/lib/pjax/lib/util/noop.js","8c3b460cdce5a650e3369c63bfccb8e5"],["/blog/lib/pjax/lib/util/update-query-string.js","4cf0e29017b579458950b03985fa4b91"],["/blog/lib/pjax/pjax.js","eb7c2c878aaf7e40958477eaf9362fd1"],["/blog/lib/pjax/pjax.min.js","5c48eff0fe69a3b607b51c597eb33951"],["/blog/lib/pjax/tests/lib/abort-request.js","92fa92a19a0f515f3b615ea6a63511b8"],["/blog/lib/pjax/tests/lib/eval-scripts.js","162f3f8090aa2d9b232539750306fcae"],["/blog/lib/pjax/tests/lib/events.js","0f8b44484c6a6ee7106b6133e8cee88a"],["/blog/lib/pjax/tests/lib/execute-scripts.js","2bdfd4dbcc3ef5f76538ad7e1217b4a5"],["/blog/lib/pjax/tests/lib/foreach-els.js","86e9dbb444e0b632ee944cfa827037f5"],["/blog/lib/pjax/tests/lib/foreach-selectors.js","fee45340269c39818ea3a051cda931ab"],["/blog/lib/pjax/tests/lib/is-supported.js","50b479ea4bb3d042d90db8700eebcee1"],["/blog/lib/pjax/tests/lib/parse-options.js","30f8242970dfb2a059de4ffb68594070"],["/blog/lib/pjax/tests/lib/proto/attach-form.js","1208c9d6f04612dbdc9b6b1a4c104226"],["/blog/lib/pjax/tests/lib/proto/attach-link.js","f8ad9b826c96e283497e4962e329e14a"],["/blog/lib/pjax/tests/lib/proto/handle-response.js","39cdab7ddcf315ddfcea09068c26b93c"],["/blog/lib/pjax/tests/lib/proto/parse-element.js","aa0b73c0a2ed1b8846933f8040d8c1ba"],["/blog/lib/pjax/tests/lib/send-request.js","263fc784b516f2a7abc12b72de951aee"],["/blog/lib/pjax/tests/lib/switch-selectors.js","95d4a0b423d581e86daf60d94e3b0c49"],["/blog/lib/pjax/tests/lib/switches.js","a6df597650eaad447047430e643f12ea"],["/blog/lib/pjax/tests/lib/uniqueid.js","d69cb621ac17b33d7d5ea90c3b12834d"],["/blog/lib/pjax/tests/lib/util/clone.js","7fb4097648cc8b252399ea1f6445caa9"],["/blog/lib/pjax/tests/lib/util/contains.js","7d0d2235138f9fa6f5694176c6aea149"],["/blog/lib/pjax/tests/lib/util/extend.js","487ff1562ba80eed3fb90e97831105c1"],["/blog/lib/pjax/tests/lib/util/noop.js","59e3460d4f796c9222b11de27dc4b177"],["/blog/lib/pjax/tests/lib/util/update-query-string.js","e9d8c6590f7a49acf8cfbc8c2e6fb662"],["/blog/lib/pjax/tests/setup.js","dcf8474136e082831fbbb3c2c5f583e0"],["/blog/lib/velocity/velocity.min.js","c1b8d079c7049879838d78e0b389965e"],["/blog/lib/velocity/velocity.ui.min.js","444faf512fb24d50a5dec747cbbe39bd"],["/blog/sw-register.js","aec3ed5c241f89483a561fb1c1990b77"],["/blog/tags/css-html/index.html","1e861cf33050f09a29f4a936694893a1"],["/blog/tags/myeclipse破解/index.html","03e93ea9ffcc54b796fed19c4c4f2312"],["/blog/tags/变量-类型/index.html","d8cfe40f7454afaf30046d93d60562fa"],["/blog/tags/同步-异步-阻塞-非阻塞/index.html","6d98520c4241daab2a2448e6fe047c73"],["/blog/tags/轻量级语言/index.html","7a60361130dab0635b8f782bdd9635b8"],["/blog/tags/高效网络库Okhttp3/index.html","78cc654d9b78d165763d13a5a96c9695"],["/blog/uploads/alipay.jpg","32d080bc69ce2c11f905991a21a1a072"],["/blog/uploads/vx.png","7e0cf4078c4337cf3cfa560e0f6ed60e"]];
var cacheName = 'sw-precache-v3--' + (self.registration ? self.registration.scope : '');
var firstRegister = 1; // 默认1是首次安装SW， 0是SW更新


var ignoreUrlParametersMatching = [/^utm_/];


var addDirectoryIndex = function (originalUrl, index) {
    var url = new URL(originalUrl);
    if (url.pathname.slice(-1) === '/') {
        url.pathname += index;
    }
    return url.toString();
};

var cleanResponse = function (originalResponse) {
    // 如果没有重定向响应，不需干啥
    if (!originalResponse.redirected) {
        return Promise.resolve(originalResponse);
    }

    // Firefox 50 及以下不知处 Response.body 流, 所以我们需要读取整个body以blob形式返回。
    var bodyPromise = 'body' in originalResponse ?
        Promise.resolve(originalResponse.body) :
        originalResponse.blob();

    return bodyPromise.then(function (body) {
        // new Response() 可同时支持 stream or Blob.
        return new Response(body, {
            headers: originalResponse.headers,
            status: originalResponse.status,
            statusText: originalResponse.statusText
        });
    });
};

var createCacheKey = function (originalUrl, paramName, paramValue,
    dontCacheBustUrlsMatching) {

    // 创建一个新的URL对象，避免影响原始URL
    var url = new URL(originalUrl);

    // 如果 dontCacheBustUrlsMatching 值没有设置，或是没有匹配到，将值拼接到url.serach后
    if (!dontCacheBustUrlsMatching ||
        !(url.pathname.match(dontCacheBustUrlsMatching))) {
        url.search += (url.search ? '&' : '') +
            encodeURIComponent(paramName) + '=' + encodeURIComponent(paramValue);
    }

    return url.toString();
};

var isPathWhitelisted = function (whitelist, absoluteUrlString) {
    // 如果 whitelist 是空数组，则认为全部都在白名单内
    if (whitelist.length === 0) {
        return true;
    }

    // 否则逐个匹配正则匹配并返回
    var path = (new URL(absoluteUrlString)).pathname;
    return whitelist.some(function (whitelistedPathRegex) {
        return path.match(whitelistedPathRegex);
    });
};

var stripIgnoredUrlParameters = function (originalUrl,
    ignoreUrlParametersMatching) {
    var url = new URL(originalUrl);
    // 移除 hash; 查看 https://github.com/GoogleChrome/sw-precache/issues/290
    url.hash = '';

    url.search = url.search.slice(1) // 是否包含 '?'
        .split('&') // 分割成数组 'key=value' 的形式
        .map(function (kv) {
            return kv.split('='); // 分割每个 'key=value' 字符串成 [key, value] 形式
        })
        .filter(function (kv) {
            return ignoreUrlParametersMatching.every(function (ignoredRegex) {
                return !ignoredRegex.test(kv[0]); // 如果 key 没有匹配到任何忽略参数正则，就 Return true
            });
        })
        .map(function (kv) {
            return kv.join('='); // 重新把 [key, value] 格式转换为 'key=value' 字符串
        })
        .join('&'); // 将所有参数 'key=value' 以 '&' 拼接

    return url.toString();
};


var addDirectoryIndex = function (originalUrl, index) {
    var url = new URL(originalUrl);
    if (url.pathname.slice(-1) === '/') {
        url.pathname += index;
    }
    return url.toString();
};

var hashParamName = '_sw-precache';
var urlsToCacheKeys = new Map(
    precacheConfig.map(function (item) {
        var relativeUrl = item[0];
        var hash = item[1];
        var absoluteUrl = new URL(relativeUrl, self.location);
        var cacheKey = createCacheKey(absoluteUrl, hashParamName, hash, false);
        return [absoluteUrl.toString(), cacheKey];
    })
);

function setOfCachedUrls(cache) {
    return cache.keys().then(function (requests) {
        // 如果原cacheName中没有缓存任何收，就默认是首次安装，否则认为是SW更新
        if (requests && requests.length > 0) {
            firstRegister = 0; // SW更新
        }
        return requests.map(function (request) {
            return request.url;
        });
    }).then(function (urls) {
        return new Set(urls);
    });
}

self.addEventListener('install', function (event) {
    event.waitUntil(
        caches.open(cacheName).then(function (cache) {
            return setOfCachedUrls(cache).then(function (cachedUrls) {
                return Promise.all(
                    Array.from(urlsToCacheKeys.values()).map(function (cacheKey) {
                        // 如果缓存中没有匹配到cacheKey，添加进去
                        if (!cachedUrls.has(cacheKey)) {
                            var request = new Request(cacheKey, { credentials: 'same-origin' });
                            return fetch(request).then(function (response) {
                                // 只要返回200才能继续，否则直接抛错
                                if (!response.ok) {
                                    throw new Error('Request for ' + cacheKey + ' returned a ' +
                                        'response with status ' + response.status);
                                }

                                return cleanResponse(response).then(function (responseToCache) {
                                    return cache.put(cacheKey, responseToCache);
                                });
                            });
                        }
                    })
                );
            });
        })
            .then(function () {
            
            // 强制 SW 状态 installing -> activate
            return self.skipWaiting();
            
        })
    );
});

self.addEventListener('activate', function (event) {
    var setOfExpectedUrls = new Set(urlsToCacheKeys.values());

    event.waitUntil(
        caches.open(cacheName).then(function (cache) {
            return cache.keys().then(function (existingRequests) {
                return Promise.all(
                    existingRequests.map(function (existingRequest) {
                        // 删除原缓存中相同键值内容
                        if (!setOfExpectedUrls.has(existingRequest.url)) {
                            return cache.delete(existingRequest);
                        }
                    })
                );
            });
        }).then(function () {
            
            return self.clients.claim();
            
        }).then(function () {
                // 如果是首次安装 SW 时, 不发送更新消息（是否是首次安装，通过指定cacheName 中是否有缓存信息判断）
                // 如果不是首次安装，则是内容有更新，需要通知页面重载更新
                if (!firstRegister) {
                    return self.clients.matchAll()
                        .then(function (clients) {
                            if (clients && clients.length) {
                                clients.forEach(function (client) {
                                    client.postMessage('sw.update');
                                })
                            }
                        })
                }
            })
    );
});



    self.addEventListener('fetch', function (event) {
        if (event.request.method === 'GET') {

            // 是否应该 event.respondWith()，需要我们逐步的判断
            // 而且也方便了后期做特殊的特殊
            var shouldRespond;


            // 首先去除已配置的忽略参数及hash
            // 查看缓存简直中是否包含该请求，包含就将shouldRespond 设为true
            var url = stripIgnoredUrlParameters(event.request.url, ignoreUrlParametersMatching);
            shouldRespond = urlsToCacheKeys.has(url);

            // 如果 shouldRespond 是 false, 我们在url后默认增加 'index.html'
            // (或者是你在配置文件中自行配置的 directoryIndex 参数值)，继续查找缓存列表
            var directoryIndex = 'index.html';
            if (!shouldRespond && directoryIndex) {
                url = addDirectoryIndex(url, directoryIndex);
                shouldRespond = urlsToCacheKeys.has(url);
            }

            // 如果 shouldRespond 仍是 false，检查是否是navigation
            // request， 如果是的话，判断是否能与 navigateFallbackWhitelist 正则列表匹配
            var navigateFallback = '';
            if (!shouldRespond &&
                navigateFallback &&
                (event.request.mode === 'navigate') &&
                isPathWhitelisted([], event.request.url)
            ) {
                url = new URL(navigateFallback, self.location).toString();
                shouldRespond = urlsToCacheKeys.has(url);
            }

            // 如果 shouldRespond 被置为 true
            // 则 event.respondWith()匹配缓存返回结果，匹配不成就直接请求.
            if (shouldRespond) {
                event.respondWith(
                    caches.open(cacheName).then(function (cache) {
                        return cache.match(urlsToCacheKeys.get(url)).then(function (response) {
                            if (response) {
                                return response;
                            }
                            throw Error('The cached response that was expected is missing.');
                        });
                    }).catch(function (e) {
                        // 如果捕获到异常错误，直接返回 fetch() 请求资源
                        console.warn('Couldn\'t serve response for "%s" from cache: %O', event.request.url, e);
                        return fetch(event.request);
                    })
                );
            }
        }
    });









/* eslint-enable */
